#pragma once

#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>


#include "Common.hpp"


const static int defaultsockfd = -1;

// const static std::string defaultip = "127.0.0.1"; // 127.0.0.1 表示本地主机
const static uint16_t defaultport = 8888;

class InetAddr
{
private:
    void PortNetToHost()
    {
        _port = ::ntohs(_net_addr.sin_port);    //_port 网络转主机, 保证大小端一致
    }

    void IpNetToHost()
    {
        char ipbuffer[64];

        //Ip 网络char.char...形式 转 主机形式"XXX.XXX. ....""
        const char* ip = ::inet_ntop(AF_INET,&_net_addr.sin_addr,ipbuffer,sizeof(ipbuffer));
        _ip = ip;
    }
public:
    InetAddr()
    {}
    InetAddr(const struct sockaddr_in& net_addr):_net_addr(net_addr)
    {
        //从网络上拿到 net_addr来初始化自己的 net_addr, 需要将 port 和 ip 从网络转换为主机
        PortNetToHost();
        IpNetToHost();
    }
    InetAddr(const uint16_t port):_port(port),_ip("")
    {
        //初始化 _net_addr 结构体中的内容
        _net_addr.sin_family = AF_INET;         
        _net_addr.sin_port = ::htons(_port);    //主机转网络
        _net_addr.sin_addr.s_addr = INADDR_ANY;     
    }

    bool operator==(const InetAddr& addr) 
    { 
        return _ip==addr._ip && _port == addr._port;
    }

    struct sockaddr* NetAddr() { return CONV(&_net_addr); }
    socklen_t SockLen() { return sizeof(_net_addr); }
    uint16_t Port() { return _port; }
    std::string Ip() { return _ip; }

    std::string Addr()
    {
        return Ip() + ":" + std::to_string(Port());
    }

    ~InetAddr()
    {}
private:
    struct sockaddr_in _net_addr;
    std::string _ip;
    uint16_t _port;
};